import $ from "jquery";
import e from "./system";

class RunLoop {
  static targets: any[] = [];
  static timer: any = undefined;
  static lastTS: number = 0;
  static inited = !1;
  static active = RunLoop.documentHidden() === !1;

  static enterFrame = (function () {
    let t = null,
      n = e.vendorJSProp(window, "requestAnimationFrame");
    return (
      n == null
        ? (t = function (e) {
            return window.setTimeout(e, 1e3 / 60);
          })
        : (t = function (e) {
            return n.call(window, e);
          }),
      t
    );
  })();

  static clearAnimationFrame = (function () {
    let t = e.vendorJSProp(window, "cancelAnimationFrame");
    t == null && (t = window.clearTimeout);
    let n = function (e) {
      t.call(window, e);
    };
    return n;
  })();

  static documentHidden() {
    let t = e.vendorJSProp(document, "hidden");
    return typeof t == "undefined" && (t = !1), t;
  }

  static onActivate() {
    if (this.active === !1) {
      this.active = !0;
      for (let e = 0; e < this.targets.length; e++) {
        let n = this.targets[e],
          r = n.target;
        typeof r["onActivate"] == "function" && r.onActivate();
      }
      this.timer != undefined &&
        (this.clearAnimationFrame(this.timer), (this.timer = undefined)),
        (this.timer = this.enterFrame(this.onFire));
    }
  }

  static onDeactivate() {
    if (this.active === !0) {
      this.active = !1;
      for (let e = 0; e < this.targets.length; e++) {
        let n = this.targets[e],
          r = n.target;
        typeof r["onDeactivate"] == "function" && r.onDeactivate();
      }
    }
  }

  static initialize() {
    if (this.inited === !1) {
      (this.inited = !0),
        window.addEventListener("blur", this.onDeactivate),
        window.addEventListener("focus", this.onActivate),
        window["onpageshow"] != undefined &&
          window["onpagehide"] != undefined &&
          (window.addEventListener("pageshow", this.onActivate),
          window.addEventListener("pagehide", this.onDeactivate));
      let n = e.addVendorPrefix("visibilitychange");
      window.addEventListener(n, () => {
        this.documentHidden() ? this.onDeactivate() : this.onActivate();
      }),
        (this.lastTS = new Date().getTime()),
        this.active && (this.timer = this.enterFrame(this.onFire)),
        (this.targets = []);
    }
  }

  static addToRunLoop(e) {
    this.initialize();
    let n = !1;
    $.each(this.targets, function (t, r) {
      return r["target"] == e ? ((n = !0), !1) : !0;
    });
    if (n) return;
    this.targets.unshift({
      target: e,
      ts: new Date().getTime(),
    });
  }

  static onFire() {
    let e = new Date().getTime(),
      n = (e - this.lastTS) / 1e3;
    for (let r = 0; r < this.targets.length; r++) {
      let i = this.targets[r],
        s = i.target;
      if (typeof s["fire"] == "function") {
        let o = (e - i.ts) / 1e3;
        s.fire.call(s, o, n);
      }
    }
    (this.lastTS = e), (this.timer = this.enterFrame(this.onFire));
  }

  static removeFromRunLoop(e) {
    for (let n = 0; n < this.targets.length; n++)
      if (this.targets[n]["target"] == e) {
        this.targets.splice(n, 1);
        break;
      }
  }
}

export default RunLoop;
